package com.baiduspring.function.elasticsearch.operation;

import org.apache.log4j.Logger;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

public class BeanUtils {
    private final static Logger LOGGER = Logger.getLogger(BeanUtils.class);

    /**
     * 将map对象转为javabean对象
     *
     * @param clazz 被转化对象Class
     * @param map   map对象
     * @return 返回JavaBean对象
     */
    public static Object map2bean(Class clazz, Map<String, Object> map) {
        BeanInfo beanInfo = null;
        try {
            //获取类属性
            beanInfo = Introspector.getBeanInfo(clazz);
        } catch (IntrospectionException e) {
            LOGGER.error("获取类属性错误：", e);
        }

        Object obj = null;
        try {
            //创建 JavaBean 对象
            obj = clazz.newInstance();
        } catch (InstantiationException e) {
            LOGGER.error("bean对象创建错误：", e);
        } catch (IllegalAccessException e) {
            LOGGER.error("bean对象创建错误：", e);
        }

        //给JavaBean对象的属性赋值
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (int i = 0; i < propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();

            if (map.containsKey(propertyName)) {
                //下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
                Object value = map.get(propertyName);

                Object[] args = new Object[1];
                args[0] = value;
                try {
                    //obj bean setter不能链式调用，否则不能设置
                    descriptor.getWriteMethod().invoke(obj, args);
                } catch (IllegalAccessException e) {
                    LOGGER.error("bean对象属性值设置错误：", e);
                } catch (IllegalArgumentException e) {
                    LOGGER.error("bean对象属性值设置错误：", e);
                } catch (InvocationTargetException e) {
                    LOGGER.error("bean对象属性值设置错误：", e);
                } catch (NullPointerException e) {
                    LOGGER.error("bean对象属性值设置错误：", e);
                }
            }
        }

        return obj;
    }
}
